<?php
/**
 * QQ登录相关函数
 * @author wangtao
 * @version 2011.05.21
 */

/**
 * 从远程服务器返回值
 * @param string	$url
 * @param int		$appid
 * @param string	$appkey
 * @param string	$access_token
 * @param string	$access_token_secret
 * @param string	$openid
 */
function doGet($url, $appid, $appkey, $access_token, $access_token_secret, $openid)
{
    $sigstr = 'GET' . '&' . rawurlencode($url).'&';

    //必要参数, 不要随便更改!!
    $params = $_GET;
    $params['oauth_version']          = '1.0';			#oAuth版本
    $params['oauth_signature_method'] = 'HMAC-SHA1';	#oAuth加密方法
    $params['oauth_timestamp']        = time();			#当前时间戳
    $params['oauth_nonce']            = mt_rand();		#随机数
    $params['oauth_consumer_key']     = $appid;			#API地址
    $params['oauth_token']            = $access_token;	#
    $params['openid']                 = $openid;
    unset($params['oauth_signature']);

    //参数按照字母升序做序列化
    $normalizedStr = getNormalizedString($params);
    $sigstr        .= rawurlencode($normalizedStr);

    //签名,确保php版本支持hash_hmac函数
    $key = $appkey . '&' . $access_token_secret;
    $signature = getSignature($sigstr, $key);
    $url      .= '?' . $normalizedStr . '&' . 'oauth_signature=' . rawurlencode($signature);

    #echo '$url\n';exit;
    return file_get_contents($url);
}

/**
 * 获取用户信息
 * @param int		$appid
 * @param string	$appkey
 * @param string	$access_token
 * @param string	$access_token_secret
 * @param string	$openid
 */
function getUserInfo($appid, $appkey, $access_token, $access_token_secret, $openid)
{
    //get user info 的api接口，不要随便更改!!
    $url    = "http://openapi.qzone.qq.com/user/get_user_info";
    return doGet($url, $appid, $appkey, $access_token, $access_token_secret, $openid);
}

/**
 * 是有效openId
 * @param int		$openid
 * @param int		$timestamp
 * @param string	$sig
 */
function isValidOpenid($openid, $timestamp, $sig)
{
    $key = $_SESSION['appkey'];
    $str = $openid.$timestamp;
    $signature = getSignature($str, $key);

    return $sig == $signature; 
}

/**
 * 得到加密串
 * @param string $str
 * @param string $key
 */
function getSignature($str, $key)
{
    $signature = '';
    $signature = base64_encode(hash_hmac('sha1', $str, $key, true));
    return $signature;
}

/**
 * 获得access token
 * @param int		$appid				应用ID
 * @param string	$appkey				应用密钥
 * @param string $request_token
 * @param string $request_token_secret
 * @param string $vericode				oauth版本
 */
function getAccessToken($appid, $appkey, $request_token, $request_token_secret, $vericode)
{
    //获取access token接口，不要随便更改!!
    $url    = 'http://openapi.qzone.qq.com/oauth/qzoneoauth_access_token?';
    //构造签名串.源串:方法[GET|POST]&uri&参数按照字母升序排列
    $sigstr = 'GET' . '&' . rawurlencode('http://openapi.qzone.qq.com/oauth/qzoneoauth_access_token') . '&';

    //必要参数，不要随便更改!!
    $params = array();
    $params['oauth_version']          = '1.0';
    $params['oauth_signature_method'] = 'HMAC-SHA1';
    $params['oauth_timestamp']        = time();
    $params['oauth_nonce']            = mt_rand();
    $params['oauth_consumer_key']     = $appid;
    $params['oauth_token']            = $request_token;
    $params['oauth_vericode']         = $vericode;

    //对参数按照字母升序做序列化
    $normalizedStr = getNormalizedString($params);
    $sigstr        .= rawurlencode($normalizedStr);

    //echo 'sigstr = $sigstr';

    //签名,确保php版本支持hash_hmac函数
    $key = $appkey . '&' . $request_token_secret;
    $signature = getSignature($sigstr, $key);
    //构造请求url
    $url      .= $normalizedStr . '&' . 'oauth_signature=' . rawurlencode($signature);

    return file_get_contents($url);
}

/**
 * 按照字母升序做序列化
 * @param array $params
 */
function getNormalizedString($params)
{
    ksort($params);
    $normalized = array();
    foreach($params as $key => $val)
    {
        $normalized[] = $key.'='.$val;
    }

    return implode('&', $normalized);
}

function redirectToLogin($appid, $appkey, $callback)
{
    //授权登录页
    $redirect = 'http://openapi.qzone.qq.com/oauth/qzoneoauth_authorize?oauth_consumer_key=' . $appid . '&';

    //获取request token
    $result = array();
    $requestToken = getRequestToken($appid, $appkey);

    parse_str($requestToken, $result);

    //request token, request token secret 需要保存起来
    //在demo演示中，直接保存在全局变量中.真实情况需要网站自己处理
    $_SESSION['token']        = $result['oauth_token'];
    $_SESSION['secret']       = $result['oauth_token_secret'];
    if ($result['oauth_token'] == '')
   {
        //demo中不对错误情况做处理
        //网站需要自己处理错误情况
        exit;
    }

    //302跳转到授权页面
    $redirect .= 'oauth_token=' . $result['oauth_token'] . '&oauth_callback=' . rawurlencode($callback);
    header("Location:$redirect");
}

function getRequestToken($appid, $appkey)
{
    //获取request token接口, 不要随便更改!!
    $url    = 'http://openapi.qzone.qq.com/oauth/qzoneoauth_request_token?';
    //构造签名串.源串:方法[GET|POST]&uri&参数按照字母升序排列
    $sigstr = 'GET' . '&' . rawurlencode('http://openapi.qzone.qq.com/oauth/qzoneoauth_request_token') . '&';

    //必要参数,不要随便更改!!
    $params = array();
    $params["oauth_version"]          = '1.0';			#oAuth版本号
    $params["oauth_signature_method"] = 'HMAC-SHA1';	#oAuth加密方法
    $params["oauth_timestamp"]        = time();			#当前时间戳
    $params["oauth_nonce"]            = mt_rand();		#随机数
    $params["oauth_consumer_key"]     = $appid;			#申请的appId

    //对参数按照字母升序做序列化
    $normalizedStr = getNormalizedString($params);	#将参数格式化成URL
    $sigstr        .= rawurlencode($normalizedStr);	#编码URL

    //签名,需要确保php版本支持hash_hmac函数
    $key = $appkey . '&';
    $signature = getSignature($sigstr, $key);
    //构造请求url
    $url      .= $normalizedStr . '&' . 'oauth_signature=' . rawurlencode($signature);

    //echo "$sigstr\n";
    //echo "$url\n";

    return file_get_contents($url);
}
